package com.framework.core.sqlfactory.jdbc;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.framework.core.dispacher.ControlDispatcher;
import com.framework.core.myexception.JdbcException;

public class BasePreparestatement {

	public static Object doQuery(String sql, Object[] args, Class<?> clazz, Type type) {

		Connection cnn = BaseJdbcConnection.getConnection();
		PreparedStatement preparedStatement = null;
		try {
			preparedStatement = cnn.prepareStatement(sql);
		} catch (SQLException e1) {
			e1.printStackTrace();
		}
		try {
			// 判断参数是否匹配
			int c = counter(sql, '?');
			if (c != 0) {
				if (c != args.length) {
					System.err.println("所传参数与sql所需要参数不匹配！");
					return null;
				}
				for (int i = 0; i < args.length; i++) {
					if (String.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("String");
						preparedStatement.setString(i + 1, String.valueOf(args[i]));
						continue;
					}
					if (char.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("char");
						preparedStatement.setString(i + 1, String.valueOf(args[i]));
						continue;
					}
					if (Byte.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("Byte");
						preparedStatement.setByte(i + 1, (Byte) args[i]);
						continue;
					}
					if (Integer.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("Integer");
						preparedStatement.setInt(i + 1, (int) args[i]);
						continue;
					}
					if (Float.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("Float");
						preparedStatement.setFloat(i + 1, (float) args[i]);
						continue;
					}
					if (Short.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("Short");
						preparedStatement.setShort(i + 1, (short) args[i]);
						continue;
					}
					if (Double.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("Double");
						preparedStatement.setDouble(i + 1, (double) args[i]);
						continue;
					}
					if (byte.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("byte");
						preparedStatement.setByte(i + 1, (byte) args[i]);
						continue;
					}
					if (int.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("int");
						preparedStatement.setInt(i + 1, (int) args[i]);
						continue;
					}
					if (float.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("float");
						preparedStatement.setFloat(i + 1, (float) args[i]);
						continue;
					}
					if (short.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("short");
						preparedStatement.setShort(i + 1, (short) args[i]);
						continue;
					}
					if (double.class.getName().equals(args[i].getClass().getClass().getName())) {
						System.out.println("double");
						preparedStatement.setDouble(i + 1, (double) args[i]);
						continue;
					}
					if (Date.class.getName().equals(args[i].getClass().getName())) {
						System.out.println("Date");
						// SimpleDateFormat sdf = new
						// SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
						// sdf.parse(new Date());
						// sdf.format(args[i])
						preparedStatement.setDate(i + 1, (java.sql.Date) args[i]);
						continue;
					}
				}
			}

			ResultSet rs = preparedStatement.executeQuery();
			Object object = null;

			// 基本类型和包装类型
			// byte---Byte
			if (byte.class.getName().equals(clazz.getName()) || Byte.class.getName().equals(clazz.getName())) {
				Byte b = null;
				int count = 0;
				rs.last(); // 移到最后一行
				count = rs.getRow();
				rs.beforeFirst();// 移到第一行
				while (rs.next()) {
					b = rs.getByte(1);
					try {
						if (count > 1) {
							throw new JdbcException("数据库返回的结果不唯一,只取第一条！");
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				return b;
			}
			// short---Short
			if (short.class.getName().equals(clazz.getName()) || Short.class.getName().equals(clazz.getName())) {
				Short s = null;
				int count = 0;
				rs.last(); // 移到最后一行
				count = rs.getRow();
				rs.beforeFirst();// 移到第一行
				while (rs.next()) {
					s = rs.getShort(1);
					try {
						if (count > 1) {
							throw new JdbcException("数据库返回的结果不唯一,只取第一条！");
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				return s;
			}
			// int---Integer
			if (int.class.getName().equals(clazz.getName()) || Integer.class.getName().equals(clazz.getName())) {
				Integer i = null;
				int count = 0;
				rs.last(); // 移到最后一行
				count = rs.getRow();
				rs.beforeFirst();// 移到第一行
				while (rs.next()) {
					i = rs.getInt(1);
					try {
						if (count > 1) {
							throw new JdbcException("数据库返回的结果不唯一,只取第一条！");
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				return i;
			}
			// long---Long
			if (long.class.getName().equals(clazz.getName()) || Long.class.getName().equals(clazz.getName())) {
				Long l = null;
				int count = 0;
				rs.last(); // 移到最后一行
				count = rs.getRow();
				rs.beforeFirst();// 移到第一行
				while (rs.next()) {
					l = rs.getLong(1);
					try {
						if (count >= 1) {
							throw new JdbcException("数据库返回的结果不唯一,只取第一条！");
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				return l;
			}
			// float---Float
			if (float.class.getName().equals(clazz.getName()) || Float.class.getName().equals(clazz.getName())) {
				Float f = null;
				int count = 0;
				rs.last(); // 移到最后一行
				count = rs.getRow();
				rs.beforeFirst();// 移到第一行
				while (rs.next()) {
					f = rs.getFloat(1);
					try {
						if (count >= 1) {
							throw new JdbcException("数据库返回的结果不唯一,只取第一条！");
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				return f;
			}
			// double---Double
			if (double.class.getName().equals(clazz.getName()) || Double.class.getName().equals(clazz.getName())) {
				Double d = null;
				int count = 0;
				rs.last(); // 移到最后一行
				count = rs.getRow();
				rs.beforeFirst();// 移到第一行
				while (rs.next()) {
					d = rs.getDouble(1);
					try {
						if (count > 1) {
							throw new JdbcException("数据库返回的结果不唯一,只取第一条！");
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				return d;
			}
			// String
			if (String.class.getName().equals(clazz.getName()) || char.class.getName().equals(clazz.getName())) {
				String s = null;
				int count = 0;
				rs.last(); // 移到最后一行
				count = rs.getRow();
				rs.beforeFirst();// 移到第一行
				while (rs.next()) {
					s = rs.getString(1);
					try {
						if (count > 1) {
							throw new JdbcException("数据库返回的结果不唯一,只取第一条！");
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				return s;
			}

			// 集合 继承Collection的
			if (Collection.class.isAssignableFrom(clazz)) {
				if (List.class.getName().equals(clazz.getName())) {
					// 获取泛型
					String className = null;
					if (type instanceof ParameterizedType) {
						for (Type fpt : ((ParameterizedType) type).getActualTypeArguments()) {
							className = fpt.getTypeName();
						}
					}
					// 判断是否基本类型和包装类型，分类包装查询结果
					// String
					if (className.equals(String.class.getName()) || className.equals(char.class.getName())) {
						List<Object> list = new ArrayList<>();
						String s = null;
						while (rs.next()) {
							s = rs.getString(1);
							list.add(s);
						}
						rs.close();
						return list;
					}
					// byte--Byte
					if (className.equals(byte.class.getName()) || className.equals(Byte.class.getName())) {
						List<Object> list = new ArrayList<>();
						Byte i = null;
						while (rs.next()) {
							i = rs.getByte(1);
							list.add(i);
						}
						rs.close();
						return list;
					}
					// short--Short
					if (className.equals(short.class.getName()) || className.equals(Short.class.getName())) {
						List<Object> list = new ArrayList<>();
						Short i = null;
						while (rs.next()) {
							i = rs.getShort(1);
							list.add(i);
						}
						rs.close();
						return list;
					}
					// int--integer
					if (className.equals(int.class.getName()) || className.equals(Integer.class.getName())) {
						List<Object> list = new ArrayList<>();
						Integer i = null;
						while (rs.next()) {
							i = rs.getInt(1);
							list.add(i);
						}
						rs.close();
						return list;
					}
					// long--Long
					if (className.equals(long.class.getName()) || className.equals(Long.class.getName())) {
						List<Object> list = new ArrayList<>();
						Long i = null;
						while (rs.next()) {
							i = rs.getLong(1);
							list.add(i);
						}
						rs.close();
						return list;
					}
					// float--Float
					if (className.equals(float.class.getName()) || className.equals(Float.class.getName())) {
						List<Object> list = new ArrayList<>();
						Float i = null;
						while (rs.next()) {
							i = rs.getFloat(1);
							list.add(i);
						}
						rs.close();
						return list;
					}
					// double--Double
					if (className.equals(double.class.getName()) || className.equals(Double.class.getName())) {
						List<Object> list = new ArrayList<>();
						Double i = null;
						while (rs.next()) {
							i = rs.getDouble(1);
							list.add(i);
						}
						rs.close();
						return list;
					}
					// Date
					if (className.equals(Date.class.getName())) {
						List<Object> list = new ArrayList<>();
						Date i = null;
						while (rs.next()) {
							i = rs.getDate(1);
							list.add(i);
						}
						rs.close();
						return list;
					}
					System.err.println("List<T> or set<T> or 自定义Bean 使用的泛型为：" + className);
					List<Object> list = new ArrayList<>();
					Class<?> forName = Class.forName(className);
					Field[] declaredFields = forName.getDeclaredFields();
					while (rs.next()) {
						object = forName.newInstance();
						for (Field field : declaredFields) {

							System.out.println(field.getType());
							System.out.println(field.getName());

							if (String.class.getName().equals(field.getType().getName())) {
								System.out.println("String");
								String s = rs.getString(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (char.class.getName().equals(field.getType().getName())) {
								System.out.println("String");
								String s = rs.getString(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (Integer.class.getName().equals(field.getType().getName())) {
								System.out.println("Integer");
								int i = rs.getInt(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, i);
								continue;
							}
							if (Float.class.getName().equals(field.getType().getName())) {
								System.out.println("Float");
								Float f = rs.getFloat(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, f);
								continue;
							}
							if (Short.class.getName().equals(field.getType().getName())) {
								System.out.println("Short");
								Short s = rs.getShort(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (Long.class.getName().equals(field.getType().getName())) {
								System.out.println("Short");
								Long s = rs.getLong(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (Double.class.getName().equals(field.getType().getName())) {
								System.out.println("Double");
								Double d = rs.getDouble(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, d);
								continue;
							}
							if (int.class.getName().equals(field.getType().getName())) {
								System.out.println("int");
								int i = rs.getInt(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, i);
								continue;
							}
							if (float.class.getName().equals(field.getType().getName())) {
								System.out.println("float");
								float f = rs.getFloat(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, f);
								continue;
							}
							if (short.class.getName().equals(field.getType().getName())) {
								System.out.println("short");
								short s = rs.getShort(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (double.class.getName().equals(field.getType().getName())) {
								System.out.println("double");
								double d = rs.getDouble(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, d);
								continue;
							}
							if (long.class.getName().equals(field.getType().getName())) {
								System.out.println("Short");
								long s = rs.getLong(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (Date.class.getName().equals(field.getType().getName())) {
								System.out.println("Date");

								Date d = rs.getDate(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, d);
								// SimpleDateFormat sdf = new
								// SimpleDateFormat("yyyy-MM-dd
								// HH:mm:ss.SSS");
								// sdf.parse(cs);
								continue;
							}
						}
						list.add(object);
					}
					rs.close();
					return list;
				}
				if (Set.class.getName().equals(clazz.getName())) {
					// 获取泛型
					String className = null;
					if (type instanceof ParameterizedType) {
						for (Type fpt : ((ParameterizedType) type).getActualTypeArguments()) {
							className = fpt.getTypeName();
						}
					}
					// 判断是否基本类型，分类封装结果
					// String
					if (className.equals(String.class.getName()) || className.equals(char.class.getName())) {
						System.out.println(String.class.getName());
						Set<Object> set = new HashSet<>();
						String s = null;
						while (rs.next()) {
							s = rs.getString(1);
							set.add(s);
						}
						rs.close();
						return set;
					}
					// byte--Byte
					if (className.equals(byte.class.getName()) || className.equals(Byte.class.getName())) {
						List<Object> list = new ArrayList<>();
						Byte i = null;
						while (rs.next()) {
							i = rs.getByte(1);
							list.add(i);
						}
						rs.close();
						return list;
					}
					// short--Short
					if (className.equals(short.class.getName()) || className.equals(Short.class.getName())) {
						Set<Object> set = new HashSet<>();
						Short i = null;
						while (rs.next()) {
							i = rs.getShort(1);
							set.add(i);
						}
						rs.close();
						return set;
					}
					// int--integer
					if (className.equals(int.class.getName()) || className.equals(Integer.class.getName())) {
						Set<Object> set = new HashSet<>();
						Integer i = null;
						while (rs.next()) {
							i = rs.getInt(1);
							set.add(i);
						}
						rs.close();
						return set;
					}
					// long--Long
					if (className.equals(long.class.getName()) || className.equals(Long.class.getName())) {
						Set<Object> set = new HashSet<>();
						Long i = null;
						while (rs.next()) {
							i = rs.getLong(1);
							set.add(i);
						}
						rs.close();
						return set;
					}
					// float--Float
					if (className.equals(float.class.getName()) || className.equals(Float.class.getName())) {
						Set<Object> set = new HashSet<>();
						Float i = null;
						while (rs.next()) {
							i = rs.getFloat(1);
							set.add(i);
						}
						rs.close();
						return set;
					}
					// double--Double
					if (className.equals(double.class.getName()) || className.equals(Double.class.getName())) {
						Set<Object> set = new HashSet<>();
						Double i = null;
						while (rs.next()) {
							i = rs.getDouble(1);
							set.add(i);
						}
						rs.close();
						return set;
					}
					// Date
					if (className.equals(Date.class.getName())) {
						Set<Object> set = new HashSet<>();
						Date i = null;
						while (rs.next()) {
							i = rs.getDate(1);
							set.add(i);
						}
						rs.close();
						return set;
					}
					System.err.println("List<T> or set<T> or 自定义Bean 使用的泛型为：" + className);
					Set<Object> set = new HashSet<>();
					// 自定义bean
					Class<?> forName = Class.forName(className);
					Field[] declaredFields = forName.getDeclaredFields();
					while (rs.next()) {
						object = forName.newInstance();
						for (Field field : declaredFields) {

							if (String.class.getName().equals(field.getType().getName())
									|| char.class.getName().equals(field.getType().getName())) {
								System.out.println("String");
								String s = rs.getString(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (Integer.class.getName().equals(field.getType().getName())) {
								System.out.println("Integer");
								int i = rs.getInt(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, i);
								continue;
							}
							if (Float.class.getName().equals(field.getType().getName())) {
								System.out.println("Float");
								Float f = rs.getFloat(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, f);
								continue;
							}
							if (Short.class.getName().equals(field.getType().getName())) {
								System.out.println("Short");
								Short s = rs.getShort(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (Long.class.getName().equals(field.getType().getName())) {
								System.out.println("Short");
								Long s = rs.getLong(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (Double.class.getName().equals(field.getType().getName())) {
								System.out.println("Double");
								Double d = rs.getDouble(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, d);
								continue;
							}
							if (int.class.getName().equals(field.getType().getName())) {
								System.out.println("int");
								int i = rs.getInt(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, i);
								continue;
							}
							if (float.class.getName().equals(field.getType().getName())) {
								System.out.println("float");
								float f = rs.getFloat(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, f);
								continue;
							}
							if (short.class.getName().equals(field.getType().getName())) {
								System.out.println("short");
								short s = rs.getShort(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (double.class.getName().equals(field.getType().getName())) {
								System.out.println("double");
								double d = rs.getDouble(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, d);
								continue;
							}
							if (long.class.getName().equals(field.getType().getName())) {
								System.out.println("Short");
								long s = rs.getLong(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, s);
								continue;
							}
							if (Date.class.getName().equals(field.getType().getName())) {
								System.out.println("Date");

								Date d = rs.getDate(field.getName());
								ControlDispatcher.setTargetBean(forName, field.getName(), object, d);
								// SimpleDateFormat sdf = new
								// SimpleDateFormat("yyyy-MM-dd
								// HH:mm:ss.SSS");
								// sdf.parse(cs);
								continue;
							}
						}
						set.add(object);
					}
					rs.close();
					return set;
				}
			}

			// 自定义bean类型
			System.err.println("List<T> or set<T> or 自定义Bean 使用的泛型为：" + clazz.getName());
			Field[] declaredFields = clazz.getDeclaredFields();
			while (rs.next()) {
				object = clazz.newInstance();
				for (Field field : declaredFields) {
					if (String.class.getName().equals(field.getType().getName())
							|| char.class.getName().equals(field.getType().getName())) {
						System.out.println("String");
						String s = rs.getString(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, s);
						continue;
					}
					if (Byte.class.getName().equals(field.getType().getName())) {
						System.out.println("Integer");
						Byte i = rs.getByte(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, i);
						continue;
					}
					if (Integer.class.getName().equals(field.getType().getName())) {
						System.out.println("Integer");
						int i = rs.getInt(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, i);
						continue;
					}
					if (Float.class.getName().equals(field.getType().getName())) {
						System.out.println("Float");
						Float f = rs.getFloat(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, f);
						continue;
					}
					if (Short.class.getName().equals(field.getType().getName())) {
						System.out.println("Short");
						Short s = rs.getShort(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, s);
						continue;
					}
					if (Long.class.getName().equals(field.getType().getName())) {
						System.out.println("Short");
						Long s = rs.getLong(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, s);
						continue;
					}
					if (Double.class.getName().equals(field.getType().getName())) {
						System.out.println("Double");
						Double d = rs.getDouble(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, d);
						continue;
					}
					if (int.class.getName().equals(field.getType().getName())) {
						System.out.println("int");
						int i = rs.getInt(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, i);
						continue;
					}
					if (float.class.getName().equals(field.getType().getName())) {
						System.out.println("float");
						float f = rs.getFloat(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, f);
						continue;
					}
					if (byte.class.getName().equals(field.getType().getName())) {
						System.out.println("Integer");
						byte i = rs.getByte(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, i);
						continue;
					}
					if (short.class.getName().equals(field.getType().getName())) {
						System.out.println("short");
						short s = rs.getShort(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, s);
						continue;
					}
					if (double.class.getName().equals(field.getType().getName())) {
						System.out.println("double");
						double d = rs.getDouble(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, d);
						continue;
					}
					if (long.class.getName().equals(field.getType().getName())) {
						System.out.println("Short");
						long s = rs.getLong(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, s);
						continue;
					}
					if (Date.class.getName().equals(field.getType().getName())) {
						System.out.println("Date");

						Date d = rs.getDate(field.getName());
						ControlDispatcher.setTargetBean(clazz, field.getName(), object, d);
						// SimpleDateFormat sdf = new
						// SimpleDateFormat("yyyy-MM-dd
						// HH:mm:ss.SSS");
						// sdf.parse(cs);
						continue;
					}
				}
			}
			rs.close();
			return object;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				cnn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return null;

	}

	// 统计sql中？出现次数
	public static int counter(String s, char c) {
		int count = 0;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) == c) {
				count++;
			}
		}
		return count;
	}

}
